package com.base.core.security.filter;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.base.core.common.http.response.AjaxResult;
import com.base.core.common.utils.JwtUtils;
import com.base.core.common.utils.UserContext;
import com.base.core.domain.User;
import com.base.core.exception.BusinessException;
import com.base.core.exception.enums.UserErrorCode;
import com.base.core.model.UserInfo;
import com.base.moduleUser.service.UserRedisService;
import com.base.moduleUser.service.UserService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class JwtAuthFilter extends OncePerRequestFilter {

    private final JwtUtils jwtUtils;

    private final UserService userService; // 改为final，强制依赖注

    private final UserRedisService userRedisService; // 改为final，强制依赖注


    //定义不需要验证的请求
    private static final List<String> ignoreUrls = Arrays.asList(
            "/virtual/user/login",
            "/virtual/upload/file",
            "/register",
            "/captcha",
            "/verifyCaptcha",
            "/logout",
            "/refreshToken");


    public JwtAuthFilter(JwtUtils jwtUtils,UserService userService,UserRedisService userRedisService) {
        this.jwtUtils = jwtUtils;
        this.userService = userService;
        this.userRedisService = userRedisService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        // 0. 忽略不需要验证的请求
        if(ignoreUrls.contains(request.getRequestURI())){
            filterChain.doFilter(request, response);
            logger.info("忽略不需要验证的请求："+request.getRequestURI());
            return;
        }

        // 1. 从请求头获取Token
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            logger.error("JWT Token 为空或格式错误");
            filterChain.doFilter(request, response); // 放行到下一个过滤器
            return;
        }

        String token = authHeader.substring(7); // 去掉"Bearer "前缀

        try {
            // 2. 验证Token有效性
            if (jwtUtils.validateToken(token)) {

                //有效的话先从缓存中获取用户信息，如果缓存中没有，则从数据库中查询
                User user = userRedisService.getUserByToken(token);
                if(user == null){
                    // 3. 从Token中提取用户名
                    String username = jwtUtils.getSubjectFromToken(token);
                    // 4. 加载用户详细信息（包括权限）
                    //UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                     user = userService.getUserByUsername(username);
                }
                List<GrantedAuthority> authorities = Arrays.asList(
                        new SimpleGrantedAuthority("ROLE_USER") // 赋予默认权限
                );
                UserInfo userInfo = new UserInfo();
                org.springframework.beans.BeanUtils.copyProperties(user, userInfo);
                //将用户信息封装到ThreadLocal中，供后续的Filter使用
                UserContext.setCurrentUser(userInfo);

                // 5. 创建认证对象
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(
                                user,
                                null, // 证书（credentials）设为null，因为JWT已经验证
                                authorities// 用户权限
                        );

                // 6. 设置到Security上下文
                SecurityContextHolder.getContext().setAuthentication(authentication);
                // 7. 继续过滤器链
                filterChain.doFilter(request, response);
            }
        } catch (BusinessException e) {
            // Token验证失败（过期/篡改等）
            returnJsonResponse(response, AjaxResult.error(e.getCode(), e.getMessage()));
//            response.setContentType("application/json");
//            response.setStatus(HttpStatus.OK.value());
//            response.getWriter().write(
//                     AjaxResult.error(e.getCode(), e.getMessage()).toString()
//            );
        }


    }
    /**
     * 返回 JSON 格式的响应
     */
    private void returnJsonResponse(HttpServletResponse response, AjaxResult result) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.setStatus(HttpServletResponse.SC_OK); // 200，前端根据 code 判断是否成功
        response.getWriter().write(JSON.toJSONString(result)); // 使用 FastJSON/Gson/Jackson 序列化
        response.getWriter().flush();
    }

}
